package control;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

import entities.tools.FilledForm;
import entities.tools.Form;
import entities.tools.Question;
import entities.users.FormSigner;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpSession;
import util.ejb.FilledFormBeanInterface;
import util.ejb.FormBeanInterface;
import util.ejb.FormFillingBeanInterface;

/**
 * Class responsible for showing dynamically created forms, and servicing sended
 * by this forms requests,
 *
 * @author Marek
 */
@WebServlet(urlPatterns = {"/form.jsp"}, loadOnStartup = 1)
public class FormServlet extends AbstractServlet1 {

    public enum Keys {

        form,
        questions,
        formSigner,
        linkHash,
        filledForm,
        formFillingBean
    }

    @EJB
    FormBeanInterface formBean;
    @EJB
    FilledFormBeanInterface filledFormBean;
    @EJB
    FormFillingBeanInterface formFillingBean;

    @Override
    protected void construct(ServletConfig config, RegisterForms registerForms, RegisterActions registerActions) {
        config.setServletName("FormServlet");
        config.setTemplateName("formTmpl.jsp");
        registerForms.registerForm(Keys.form.name(), FormKey.processFormOne);
    }

    @Override
    protected void initSesionVars(HttpSession session, RegisterParameter params, RegisterError errors) throws ServletException, BreakProcessException, RedirectRequest {
        if (!params.doParameterExist(Keys.linkHash.name())) {
            throw new BreakProcessException("FormServlet->initSessionVars():FormDontExist", "formDontExist.jsp");
        }
        String linkHash = params.readParameter(Keys.linkHash.name())[0];
        //TODO:Optymalization -> Instread of reading whole object from session we can perform this check by simple select query :-)
        FilledForm filledForm = filledFormBean.getFilledForm(linkHash);
        if (null == filledForm) {
            throw new BreakProcessException("FormServlet->initSessionVars():FormDontExist", "formDontExist.jsp");
        }
        List<Question> questions = formBean.getAllQuestions(filledForm.getForm());
        session.setAttribute(Keys.filledForm.name(), filledForm);
        session.setAttribute(Keys.questions.name(), questions);
        session.setAttribute(Keys.linkHash.name(), linkHash);
    }

    @Override
    protected void load(HttpSession session, RegisterParameter params, RegisterError errors) throws ServletException, IOException, BreakProcessException, RedirectRequest {
        //TODO: here we should perform linkHash check :-)
    }

    @Override
    protected void save(HttpSession session, RegisterParameter params, RegisterError errors) throws ServletException, IOException, BreakProcessException, RedirectRequest {
        //TODO: do we any variables saved post processing?   
    }

    /**
     *
     */
    @Override
    protected void processFormOne(HttpSession session, RegisterParameter parameters, RegisterError errors) throws ServletException, IOException, BreakProcessException, RedirectRequest, CleanServletRequest {
        errors.clearErrors();
        String linkHash = (String) session.getAttribute(Keys.linkHash.name());
        String tmpLinkHash = parameters.readParameter(Keys.linkHash.name())[0];
        if (tmpLinkHash != linkHash) {
            linkHash = tmpLinkHash;
        }
        FilledForm filledForm = (FilledForm) session.getAttribute(Keys.filledForm.name());
        Form form = filledForm.getForm();
        Long sendedFormId = null;
        sendedFormId = new Long(parameters.readParameter("formId")[0]);
        if (form.getId().intValue() != sendedFormId.intValue()) {
            throw new ServletException("Form sended by you, is different, than the form registered on server");
        }
        FormSigner formSigner = filledForm.getFormSigner();
        List<Question> questions = form.getQuestions();

        //Check if all required data have been sended
        for (Question question : questions) {
            if (!parameters.doParameterExist("question-" + question.getId())) {
                errors.registerError("question-" + question.getId(), "Odpowiedź obowiązkowa.");
            }
            String type = parameters.readParameter("question-" + question.getId() + "-type")[0];
            if (type.equals("radio")) {

            }
            if (type.equals("grid")) {
                String[] values = parameters.readParameter("question-" + question.getId());
                int countNullValue = 0;
                for (String value : values) {
                    if (value.equals("null") || value.equals("")) {
                        countNullValue++;
                    }
                }
                if (countNullValue != 0 && countNullValue != values.length) {
                    errors.registerError("question-" + question.getId(), "Nie wypełniłeś całego wiersza.");
                }
            }
        }
        if (!errors.areErrors()) {
            this.formFillingBean.beginFillingForm(linkHash);
            for (Question question : questions) {
                String type = parameters.readParameter("question-" + question.getId() + "-type")[0];
                //TODO: Where the exceept of the code responsible for servicing different question types should be putted
                if (type.equals("radio")) {
                    //IDEA: use filter, and a wraper to return direct answer values instead of parameters :-) Code will be cleaner
                    //TODO: how to use bean validation here
                    //TODO: Create special wrapper class converting parameters to answers, and answers to parameters
                    String answerValue = "" + parameters.readParameter("question-" + question.getId())[0] + ",";
                    this.formFillingBean.answerQuestion(question, answerValue);
                }
                if (type.equals("grid")) {
                    String answerValue = "";
                    String[] values = parameters.readParameter("question-" + question.getId());
                    for (String value : values) {
                        if (value.equals("null") || value.equals("")) {
                            value = null;
                        }
                        answerValue += value + "¶";
                    }
                    this.formFillingBean.answerQuestion(question, answerValue);
                }
            }
            if (true == this.formFillingBean.sendForm()) {
                throw new CleanServletRequest("thankYou.jsp");
            }
        }

    }

    @Override
    protected void beforeExit(HttpSession session, RegisterParameter registerParam, RegisterError registerError) {
        session.removeAttribute(Keys.filledForm.name());
        session.removeAttribute(Keys.questions.name());
        session.removeAttribute(Keys.linkHash.name());
    }
}
